package com.iussoft.tdengine.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.iussoft.tdengine.util.StringUtil;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Map;

/**
 * @description: 数据源初始父类
 * @author: Hou Dayu
 * @date: Created in 2020/11/6
 */
public abstract class AbstractDataSource {

    protected int maxActive = 20;
    protected long maxWate = 60000;
    protected int minIdle = 5;
    protected int initialSize = 5;
    protected Map<Object, DataSource> targetDataSources;
    protected DataSource defaultDataSource;
    private String datasourceKey;
    protected String datasourceKeys;
    protected TDDatasource tdDatasource;

    public abstract void afterPropertiesSet();

    protected abstract Object determineCurrentLookupKey();

    public abstract Connection getConnection() throws SQLException;

    protected void buildDefaultDatasource() {
        if(null != tdDatasource) {
            DruidDataSource dfds = initDataSource(tdDatasource.getUrl(),tdDatasource.getDiverClassName(),tdDatasource.getUsername(),tdDatasource.getPassword());
            if(tdDatasource.getMaxActive()>0)
            dfds.setMaxActive(tdDatasource.getMaxActive());
            if(tdDatasource.getInitialSize()>0)
            dfds.setInitialSize(tdDatasource.getInitialSize());
            if(tdDatasource.getMinIdle()>0)
            dfds.setMinIdle(tdDatasource.getMinIdle());
            if(tdDatasource.getMaxWate()>0)
            dfds.setMaxWait(tdDatasource.getMaxWate());
            defaultDataSource = dfds;
            this.targetDataSources = new Hashtable();
            targetDataSources.put("default",defaultDataSource);
            setDatasourceKey("default");
        }
    }

    protected DataSource determineTargetDataSource() {
        Object lookupKey = determineCurrentLookupKey();
        String key = String.valueOf(lookupKey);
        DataSource dataSource = null;
        if(StringUtil.isNull(key)){
            return defaultDataSource;
        }
        dataSource = targetDataSources.get(key);
        if(null == dataSource){
            throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
        }
        return dataSource;
    }

    public String getDatasourceKey() {
        return datasourceKey;
    }

    protected void setDatasourceKey(String datasourceKey) {
        this.datasourceKey = datasourceKey;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public void setMaxWate(long maxWate) {
        this.maxWate = maxWate;
    }

    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    public void setInitialSize(int initialSize) {
        this.initialSize = initialSize;
    }

    public void setTdDatasource(TDDatasource tdDatasource) {
        this.tdDatasource = tdDatasource;
    }

    public void setDatasourceKeys(String datasourceKeys) {
        this.datasourceKeys = datasourceKeys;
    }

    /**
     * 实例数据库连接池
     */
    protected DruidDataSource initDataSource(String url, String driver, String user, String password) {
        DruidDataSource dsss = new DruidDataSource();
        dsss.setDriverClassName(StringUtil.doNull(driver,"com.taosdata.jdbc.TSDBDriver"));//com.taosdata.jdbc.TSDBDriver
        dsss.setUrl(url);//jdbc:TAOS://127.0.0.1:6030/test
        dsss.setUsername(user);
        dsss.setPassword(password);
        dsss.setInitialSize(initialSize);
        dsss.setMaxActive(maxActive);
        dsss.setMinIdle(minIdle);
        dsss.setMaxWait(maxWate);//最大等待时间，当没有可用连接时，连接池等待连接释放的最大时间
        dsss.setRemoveAbandonedTimeout(180);//超过时间限制，回收没有用(废弃)的连接
        dsss.setRemoveAbandoned(true);//超过removeAbandonedTimeout时间后，是否进 行没用连接（废弃）的回收
//        dsss.setPoolPreparedStatements(true);//开启池的prepared statement 池功能
//        dsss.setMaxPoolPreparedStatementPerConnectionSize(50);
        return dsss;
    }

}
